#include <REGX52.H>

sbit LCD_RW = P2^5;
sbit LCD_RS = P2^6;
sbit LCD_E = P2^7;

#define LCD_DataPort P0

// LCD专用延时函数
void LCD_Delay()		//@11.0592MHz 1ms
{
	unsigned char i, j;
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}

// LCD写命令
// 写命令 —— 写/命令
void LCD_WriteCommand(unsigned char Command){
	// LCD_RS清零 —— 准备发送
	LCD_RS = 0;
	// LCD_RW 清零 —— 用于写入
	LCD_RW = 0;
	// 打开使能并延时
	LCD_E = 1;
	LCD_Delay();
	// 写入数据
	LCD_DataPort = Command;
	// 关闭使能
	LCD_E = 0;
	LCD_Delay();
	
}

// LCD写数据
// 写数据 —— 写/数据
void LCD_WriteData(unsigned char Data){
	//LCD_RS置位 —— 准备发送
	LCD_RS = 1;
	// LCD_RW清零
	LCD_RW = 0;
	// 打开使能并延时
	LCD_E = 1;
	LCD_Delay();
	//输入数据
	LCD_DataPort = Data;
	// 关闭使能并延时
	LCD_E = 0;
	LCD_Delay();
}

// LCD初始化
void LCD_Init(){
	// LCD设置为8位数据接口，两行显示5x7点阵
	LCD_WriteCommand(0x38);
	// 显示开关控制 —— 显示开，光标关，闪烁关
	LCD_WriteCommand(0x0c);
	// LCD设置为在数据读写操作后，AC自动加一；画面不动
	LCD_WriteCommand(0x06);
	//清屏
	LCD_WriteCommand(0x01);
}

// 设置光标位置
void LCD_SetCursor(unsigned char Line,unsigned char Column){
	if(Line == 1){
		LCD_WriteCommand( 0x80 | (Column - 1));
	}
	else{
		LCD_WriteCommand( 0xC0 | (Column - 1));
	}
}

void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char){
	// 设置光标位置
	LCD_SetCursor(Line,Column);
	// 显示字符
	LCD_WriteData(Char);
}


void LCD_ShowString(unsigned char Line,unsigned char Column,unsigned char* String){
	unsigned i = 0;
	//设置光标位置
	LCD_SetCursor(Line,Column);
	// 将字符一个个显示出来
	while(String[i] != '\0'){
		LCD_WriteData(String[i]);
		i++;
	}
}

void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length){
	// 设置一个全为0的数组
	unsigned int Data[5] = {0};
	// i用来索引下标 —— 从后往前存
	unsigned char i = Length -1 ;
	while(Number){
		Data[i] = Number % 10;
		Number /= 10;
		i--;
	}
	// 设置光标位置
	LCD_SetCursor(Line,Column);
	// 一位位输出
	for( i = 0 ; i < Length; i++){
		LCD_WriteData(0x30 + Data[i]);
	}
}

void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length){
	// 设置一个全为0的数组
	unsigned int Data[5] = {0};
	// i用来索引下标 —— 从后往前存
	unsigned char i = Length -1 ;
	// abs变量用于存取绝对值
	unsigned int abs = (Number > 0) ? Number : -Number;
	while(abs){
		Data[i] = abs % 10;
		abs /= 10;
		i--;
	}
	// 设置光标位置
	LCD_SetCursor(Line,Column);
	// 一位位输出
	LCD_WriteData((Number > 0) ? '+' : '-');
	for( i = 0 ; i < Length; i++){
		LCD_WriteData(0x30 + Data[i]);
	}
}

// 显示二进制数
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length){
	// 设置一个全为0的数组
	unsigned int Data[16] = {0};
	// i用来索引下标 —— 从后往前存
	unsigned char i = Length -1 ;
	while(Number){
		Data[i] = Number % 2;
		Number /= 2;
		i--;
	}
	// 设置光标位置
	LCD_SetCursor(Line,Column);
	// 一位位输出
	for( i = 0 ; i < Length; i++){
		LCD_WriteData(0x30 + Data[i]);
	}
}

// 显示十六进制数
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length){
	// 设置一个全为0的数组
	unsigned int Data[4] = {0};
	// i用来索引下标 —— 从后往前存
	unsigned char i = Length -1 ;
	while(Number){
		Data[i] = Number % 16;
		Number /= 16;
		i--;
	}
	// 设置光标位置
	LCD_SetCursor(Line,Column);
	// 一位位输出
	for( i = 0 ; i < Length; i++){
		LCD_WriteData(0x30 + (Data[i] > 9 ? (Data[i] + 7) : Data[i]));
	}
}

// 将用户自定义字符写入CGRAM
void LCD_SetCustomChar(unsigned char Position,char *Table){
	unsigned char i;
	switch (Position)
	{
		case 1:
			LCD_WriteCommand(0x40);
		break;
		case 2:
			LCD_WriteCommand(0x48);
		break;
		case 3:
			LCD_WriteCommand(0x50);
		break;
		case 4:
			LCD_WriteCommand(0x58);
		break;
		case 5:
			LCD_WriteCommand(0x60);
		break;
		case 6:
			LCD_WriteCommand(0x68);
		break;
		case 7:
			LCD_WriteCommand(0x70);
		break;
		case 8:
			LCD_WriteCommand(0x78);
		break;
	}
	for(i=0;i<8;i++){
		LCD_WriteData(Table[i]);	
	}
}

// 输出CGRAM中的自定义字符
void LCD_ShowCustomChar(unsigned char Line,unsigned char Column,unsigned char Num)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Num-1);
}



